package com.eastfair.venuebooking.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.eastfair.annotation.annotation.log.SysLog;
import com.eastfair.annotation.annotation.security.PreAuth;
import com.eastfair.boot.controller.SuperController;
import com.eastfair.boot.request.PageParams;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.base.entity.SuperEntity;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.echo.core.EchoService;
import com.eastfair.venuebooking.dto.*;
import com.eastfair.venuebooking.entity.Exhibition;
import com.eastfair.venuebooking.entity.ExhibitionSegment;
import com.eastfair.venuebooking.enums.SegmentNameEnum;
import com.eastfair.venuebooking.exceptioncode.VenueBookingExceptionCode;
import com.eastfair.venuebooking.service.ExhibitionSegmentService;
import com.eastfair.venuebooking.service.ExhibitionService;
import com.eastfair.venuebooking.vo.ExhibitionSegmentVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * <p>
 * 前端控制器
 * 环节
 * </p>
 *
 * @author linan
 * @date 2022-06-08
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/exhibitionSegment")
@Api(value = "ExhibitionSegment", tags = "环节")
@PreAuth(replace = "venuebooking:exhibitionSegment:")
public class ExhibitionSegmentController extends SuperController<ExhibitionSegmentService, Long, ExhibitionSegment, ExhibitionSegmentPageQuery, ExhibitionSegmentSaveDTO, ExhibitionSegmentUpdateDTO> {

    @Autowired
    private EchoService echoService;
    @Resource
    private ExhibitionService exhibitionService;

    @Override
    public void handlerResult(IPage<ExhibitionSegment> page) {
        // 想让返回值实现自动回显，请将此行代码打开
        // echoService.action(page);
    }
    /**
     * Excel导入后的操作
     *
     * @param list
     */
    @Override
    public R<Boolean> handlerImport(List<Map<String, String>> list){
        List<ExhibitionSegment> exhibitionSegmentList = list.stream().map((map) -> {
            ExhibitionSegment exhibitionSegment = ExhibitionSegment.builder().build();
            //TODO 请在这里完成转换
            return exhibitionSegment;
        }).collect(Collectors.toList());

        return R.success(baseService.saveBatch(exhibitionSegmentList));
    }



    /**
     * 处理参数
     *
     * @param params 分页参数
     */
    @Override
    public void handlerQueryParams(PageParams<ExhibitionSegmentPageQuery> params) {
        ExhibitionSegmentPageQuery pageQuery = params.getModel();
        //分页处理
        if(ContextUtil.getProjectId()!=null){
            pageQuery.setProjectId(ContextUtil.getProjectId());
        }
    }

    /**
     * 添加展会环节
     *
     * @param exhibitionSegmentSaveDTO 添加展会环节
     * @return
     */
    @ApiOperation(value = "添加展会环节", notes = "添加展会环节")
    @SysLog("添加展会环节")
    @PostMapping("/addExhibitionSegment")
    public R addExhibitionSegment(@RequestBody @Validated({ExhibitionSegmentDTO.Check.class}) ExhibitionSegmentDTO exhibitionSegmentSaveDTO) {
        log.info("addExhibitionSegment - 添加展会环节   exhibitionSegmentSaveDTO: {}",exhibitionSegmentSaveDTO);
        if(exhibitionSegmentSaveDTO.getStartTime().isAfter(exhibitionSegmentSaveDTO.getEndTime())){
            throw BizException.wrap(VenueBookingExceptionCode.EX_CANT_START_MORE_TRAN_END);
        }
        return R.success(baseService.addExhibitionSegment(exhibitionSegmentSaveDTO));
    }

    /**
     * 查询展会环节列表
     *
     * @param exhibitionId 查询展会环节列表
     * @return
     */
    @ApiOperation(value = "查询展会环节列表", notes = "查询展会环节列表")
    @GetMapping("/querySegmentByExhibitionId")
    public R querySegmentByExhibitionId(@RequestParam("exhibitionId") @Validated @NotNull(message = "展会ID必填") Long exhibitionId) {
        log.info("querySegmentByExhibitionId - 查询展会环节列表   exhibitionId: {}",exhibitionId);
        QueryWrapper<ExhibitionSegment> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(ExhibitionSegment::getIsDeleted, BusinessConstant.NO)
                .eq(ExhibitionSegment::getExhibitionId,exhibitionId)
                //  创建环节的时候支持日期重叠；2、排序规则按照开始日期靠前排序，然后根据结束日期靠前排序，创建同一个周期段的按照创建优先级排序
                .orderByAsc(ExhibitionSegment::getStartTime)
                .orderByAsc(ExhibitionSegment::getEndTime)
                .orderByAsc(ExhibitionSegment::getCreateTime);
        return R.success(ConvertUtil.convertList(baseService.list(qw), ExhibitionSegmentVO.class));
    }

    /**
     * 修改展会环节
     *
     * @param exhibitionSegmentUpdateDTO 修改展会环节
     * @return
     */
    @ApiOperation(value = "修改展会环节", notes = "修改展会环节")
    @SysLog("修改展会环节")
    @PostMapping("/updateExhibitionSegment")
    public R updateExhibitionSegment(@RequestBody @Validated({ExhibitionSegmentDTO.Check.class, SuperEntity.Update.class}) ExhibitionSegmentDTO exhibitionSegmentUpdateDTO) {
        log.info("updateExhibitionSegment - 修改展会环节   exhibitionSegmentUpdateDTO: {}",exhibitionSegmentUpdateDTO);
        if(exhibitionSegmentUpdateDTO.getStartTime().isAfter(exhibitionSegmentUpdateDTO.getEndTime())){
            throw BizException.wrap(VenueBookingExceptionCode.EX_CANT_START_MORE_TRAN_END);
        }
        ExhibitionSegment updateEntity = new ExhibitionSegment();
        BeanUtils.copyProperties(exhibitionSegmentUpdateDTO,updateEntity);
        updateEntity.setId(exhibitionSegmentUpdateDTO.getId());
        return R.success(baseService.updateById(updateEntity));
    }

    /**
     * 环节管理
     *
     * @param exhibitionSegmentUpdates 环节管理
     * @return
     */
    @ApiOperation(value = "环节管理", notes = "环节管理")
    @PostMapping("/exhibitionSegmentManage")
    public R exhibitionSegmentManage(@RequestBody @Validated({ExhibitionSegmentDTO.Check.class, SuperEntity.Update.class}) List<ExhibitionSegmentDTO> exhibitionSegmentUpdates) {
        log.info("exhibitionSegmentManage - 环节管理   exhibitionSegmentUpdateDTOS: {}",exhibitionSegmentUpdates);
        List<ExhibitionSegmentDTO> updateList = new ArrayList<>();
        List<ExhibitionSegmentDTO> addList = new ArrayList<>();
        for (ExhibitionSegmentDTO exhibitionSegmentUpdateDTO : exhibitionSegmentUpdates) {
            if(exhibitionSegmentUpdateDTO.getStartTime().isAfter(exhibitionSegmentUpdateDTO.getEndTime())){
                throw BizException.wrap(VenueBookingExceptionCode.EX_CANT_START_MORE_TRAN_END);
            }
            if(Objects.nonNull(exhibitionSegmentUpdateDTO.getId())){
                updateList.add(exhibitionSegmentUpdateDTO);
            }else {
                exhibitionSegmentUpdateDTO.setDeleteable(true);
                addList.add(exhibitionSegmentUpdateDTO);
            }
        }
        for (ExhibitionSegmentDTO exhibitionSegmentDTO : updateList) {
            updateExhibitionSegment(exhibitionSegmentDTO);
        }
        for (ExhibitionSegmentDTO exhibitionSegmentDTO : addList) {
            baseService.addExhibitionSegment(exhibitionSegmentDTO);
        }
        return R.success();
    }

    /**
     * 删除展会环节
     *
     * @param id 环节ID
     * @return R
     */
    @ApiOperation(value = "删除展会环节", notes = "删除展会环节")
    @SysLog("删除展会环节")
    @GetMapping("/removeSegment")
    public R removeSegment(@RequestParam("id") @Validated @NotNull(message = "环节ID必填") Long id) {
        log.info("removeSegment - 删除展会环节   id: {}",id);
        ExhibitionSegment segment = baseService.getById(id);
        if (Objects.isNull(segment)) {
            return R.fail(VenueBookingExceptionCode.RE_NOT_FIND.getMsg());
        } else if (Objects.nonNull(segment.getDeleteable()) && !segment.getDeleteable()) {
            return R.fail(VenueBookingExceptionCode.SG_CANT_REMOVE.getMsg());
        } else {
            return R.success(baseService.updateById(ExhibitionSegment.builder().id(id).isDeleted(BusinessConstant.YES).build()));
        }
    }

}
